import {
    Box,
    Button,
    Card,
    CardContent,
    Checkbox,
    Container,
    FormControlLabel,
    Grid,
    Typography
} from '@mui/material';
import { makeStyles } from '@mui/styles';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
import Countdown from 'react-countdown';

import { AuthenticationType } from '../api/authentication/authentication';
import AuthenticationManager from '../api/authentication/authentication-manager';
import OTPManager from '../api/otp/otp-manager';
import OtpInput from '../components/otp/otp-input';
import OTPMessage from '../components/otp/otp-message';
import { createDialog } from '../components/shared/dialogs/dynamic-dialogs';
import { DialogTypes } from '../components/shared/dialogs/dynamic-dialogs/types-mapping';
import { termOfServiceDialog } from '../components/shared/dialogs/terms-of-services';
import { BRANDING } from '../constants/branding';
import { OTPStatus } from '../constants/otp-status';
import Routes from '../constants/routes';
import { RETURN_URL } from '../constants/storage-key';

const otpStyle = makeStyles(() => ({
    '.container-galaxy': {
        height: 'calc(100vh)',
        backgroundImage: 'url(/galaxy-bg.svg)',
        backgroundSize: 'cover'
    },
    '.otp-container': {
        marginLeft: 'auto 0px !important',
        marginRight: 'auto 0px !important',
        textAlign: 'center',
        display: 'flex',
        marginTop: '2.5rem'
    },
    '.otp-input': {
        width: '4rem !important',
        height: '4rem !important',
        color: 'var(--color-white)',
        background: 'rgba(255, 255, 255, 0.16)',
        border: '0.632692px solid rgba(255, 255, 255, 0.21)',
        boxSizing: 'border-box',
        boxShadow: '0px 1.38037px 2.76075px rgba(0, 0, 0, 0.075)',
        borderRadius: '5.38462px'
    },
    '.countdown': {
        color: '#E1E1E1 !important',
        textDecoration: 'none'
    },
    '.resend': {
        color: '#38AFFE !important'
    }
}));

const OTPPage = () => {
    const styles = otpStyle();
    const router = useRouter();
    const [otp, setOTP] = useState('');
    const [status, setStatus] = useState(OTPStatus.SENDING_OTP);
    const [error, setError] = useState('');
    const [timeToRequest, setTimeToRequest] = useState(0);
    const [confirmed, setConfirmed] = useState<boolean>(false);

    useEffect(() => {
        checkAuthenticationAndRedirect().then();
    }, []);

    const checkAuthenticationAndRedirect = async () => {
        const valid = await AuthenticationManager.isValid();
        if (valid === AuthenticationType.VALID) {
            router.push(Routes.HOME).then();
        } else {
            sendOTP().then();
        }
    };

    const sendOTP = async () => {
        setStatus(OTPStatus.SENDING_OTP);
        setOTP('');

        const response = await OTPManager.send();

        if (response) {
            if (response.sent == true) {
                setTimeToRequest(Date.now() + 60000);
                setStatus(OTPStatus.EMAIL_SENT);
            } else if (response.timeRemaining) {
                setTimeToRequest(Date.now() + response.timeRemaining);
                setStatus(OTPStatus.EMAIL_SENT);
            } else {
                showError();
            }
        } else {
            showError();
        }
    };

    const showError = () => {
        setError('OTP not sent. Please try again later.');
        setStatus(OTPStatus.INVALID_OTP);
    };

    const onChange = (otp: string) => {
        setOTP(otp);
    };

    const onSubmit = async () => {
        setStatus(OTPStatus.CHECKING_OTP);
        if (otp === '') {
            setError('Enter your OTP to verify access.');
            setStatus(OTPStatus.INVALID_OTP);
            return;
        }

        const response = await OTPManager.check(otp);

        if (response.authentication) {
            AuthenticationManager.setKey(response.authentication.key);
            AuthenticationManager.setSecret(response.authentication.secret);

            const returnURL = localStorage.getItem(RETURN_URL);
            if (returnURL) {
                localStorage.removeItem(RETURN_URL);
                router.push(returnURL).then();
            } else {
                router.push(Routes.HOME).then();
            }
        } else if (response.error) {
            setError(response.error);
            setStatus(OTPStatus.INVALID_OTP);
        } else {
            setStatus(OTPStatus.INVALID_OTP);
        }
    };

    const renderCountdown = ({ seconds, completed }) => {
        if (completed) {
            return (
                <Button variant="text" className={styles['.resend']} onClick={sendOTP}>
                    Request New OTP
                </Button>
            );
        } else {
            return <small className={styles['.countdown']}>Resend after {seconds} seconds</small>;
        }
    };

    const renderCountdownComponent = () => {
        // @ts-ignore
        return <Countdown renderer={renderCountdown} date={timeToRequest} />;
    };

    return (
        <>
            <style jsx global>{`
                .container-galaxy {
                    width: 100%;
                    height: 100%;
                    background-image: url(/new-bg-manager.svg);
                    background-repeat: no-repeat;
                    background-position: center;
                    background-size: contain;
                }

                .content {
                    width: 100%;
                    height: 100%;
                    display: flex;
                    flex-direction: column;
                    align-items: flex-start;
                }

                .logo {
                    color: white;
                    margin-top: 40px;
                    margin-bottom: 30px;
                }

                .card {
                    background: linear-gradient(
                        167.17deg,
                        rgba(4, 1, 23, 0.61) -8.99%,
                        rgba(79, 78, 249, 0.61) 93.4%
                    );
                    box-shadow: 0px 3.61798px 12.6629px rgba(147, 20, 254, 0.18);
                    border-radius: 4px;
                }

                .card-icon {
                    margin-top: 20px;
                }

                .card-title {
                    margin-top: 10px;
                    color: #ffffff;
                }

                .card-description {
                    color: #ffffff;
                    margin-top: 10px;
                }

                .card-content {
                    opacity: 1 !important;
                }

                .otp-divider {
                    width: 20px;
                    height: 1px;
                    background: #ffffff;
                    margin-left: 10px;
                    margin-right: 10px;
                }

                .button {
                    background: rgba(144, 22, 254, 0.75);
                    border-radius: 4px;
                    width: 200px;
                }

                .button:hover {
                    background: rgba(144, 22, 254, 0.9);
                }

                .message {
                    opacity: 0.9;
                    margin-top: 40px;
                    margin-bottom: 30px;
                }

                @media screen and (max-width: 600px) {
                    .container-galaxy {
                        height: calc(100vh - 56px);
                        margin-top: 56px;
                    }
                }
            `}</style>

            <Box className={styles['.container-galaxy']}>
                <Box className={'galaxy'}>
                    <Box className={'content'}>
                        <Container>
                            <Typography variant="h2" className={'logo'}>
                                {BRANDING.NAME} Admin
                            </Typography>

                            <Grid container justifyContent="center">
                                <Grid item xs={12} md={8}>
                                    <Card className={'card'}>
                                        <CardContent className={'card-content'}>
                                            <Grid container justifyContent="center">
                                                <img
                                                    alt="otp"
                                                    src="/otp-icon.svg"
                                                    width={80}
                                                    height={80}
                                                    className={'card-icon'}
                                                />
                                            </Grid>

                                            <Typography
                                                variant="h2"
                                                align="center"
                                                className={'card-title'}
                                            >
                                                Verification
                                            </Typography>

                                            {status != OTPStatus.SENDING_OTP ? (
                                                <>
                                                    <Typography
                                                        variant="body2"
                                                        className={'card-description'}
                                                        align="center"
                                                    >
                                                        Enter the One-Time Password sent to your
                                                        email
                                                    </Typography>
                                                    <Grid
                                                        container
                                                        justifyContent="center"
                                                        className="top-40"
                                                    >
                                                        <OtpInput
                                                            value={otp}
                                                            onChange={onChange}
                                                            numInputs={6}
                                                            isInputNum={true}
                                                            isDisabled={
                                                                status == OTPStatus.CHECKING_OTP
                                                            }
                                                            inputStyle={styles['.otp-input']}
                                                            separator={
                                                                <div className={'otp-divider'} />
                                                            }
                                                        />
                                                    </Grid>
                                                    <Grid
                                                        container
                                                        justifyContent="center"
                                                        className="top-10"
                                                    >
                                                        {renderCountdownComponent()}
                                                    </Grid>
                                                    <FormControlLabel
                                                        className="w-100 justify-content-center"
                                                        control={
                                                            <Checkbox
                                                                checked={confirmed}
                                                                onChange={(e) =>
                                                                    setConfirmed(e.target.checked)
                                                                }
                                                            />
                                                        }
                                                        label={
                                                            <Typography
                                                                variant="h5"
                                                                align={'center'}
                                                                className={
                                                                    'my-4 d-flex justify-content-center'
                                                                }
                                                                sx={{ gap: 1 }}
                                                            >
                                                                By using our app, you agree to our{' '}
                                                                <Typography
                                                                    sx={{
                                                                        cursor: 'pointer',
                                                                        color: 'var(--color-warning)',
                                                                        '&:hover': {
                                                                            textDecoration:
                                                                                'underline'
                                                                        }
                                                                    }}
                                                                    onClick={() =>
                                                                        createDialog(
                                                                            DialogTypes.TERMS_OF_SERVICES,
                                                                            () =>
                                                                                termOfServiceDialog(
                                                                                    () =>
                                                                                        !confirmed &&
                                                                                        setConfirmed(
                                                                                            true
                                                                                        )
                                                                                )
                                                                        )
                                                                    }
                                                                >
                                                                    Terms and Service
                                                                </Typography>
                                                            </Typography>
                                                        }
                                                    />
                                                    <Grid container justifyContent="center">
                                                        <Button
                                                            variant="contained"
                                                            size="large"
                                                            onClick={onSubmit}
                                                            disabled={
                                                                status == OTPStatus.CHECKING_OTP ||
                                                                !confirmed
                                                            }
                                                            className={'button'}
                                                        >
                                                            VERIFY
                                                        </Button>
                                                    </Grid>
                                                    <Grid container justifyContent="center">
                                                        <OTPMessage status={status} error={error} />
                                                    </Grid>
                                                </>
                                            ) : (
                                                <Grid container justifyContent="center">
                                                    <OTPMessage status={status} error={error} />
                                                </Grid>
                                            )}
                                        </CardContent>
                                    </Card>
                                </Grid>
                            </Grid>
                        </Container>
                    </Box>
                </Box>
            </Box>
        </>
    );
};

export default OTPPage;
